home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekkan Dennou Club 147
/
Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z
/
Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin
/
tools
/
ask
/
ksd
/
source
/
ksd.s
< prev
next >
Wrap
Text File
|
1998-10-01
|
42KB
|
1,523 lines
*********************************************************************
* キー入力・シミュレート・ドライバー
* KSD V1.7
* Copyright (C) 1997,98 by AIG-Soft
*********************************************************************
.include defines.mac
.include fefunc.dis
.include pspdef.mac
.include skey.mac
.include ksd.mac
* モード定数(0および正負は変えないこと)
MD_OnceActive equ -2
MD_BuffActive equ -1
MD_Active equ 0
MD_Pause equ 1
MD_Stop equ 2
*********************************************************************
* 常駐ルーチン
*********************************************************************
.text
.even
DevHead: * デバイスヘッダー(ファイル先頭に必要)
.dc.l -1 * next device none
.dc.w %11000000_00000000 * char device/IOCTRL ok/Cooked
* ?? ? 0000
.dc.l Dev_start
.dc.l Dev_main
DevName .dc.b '@KEY ' * devive name
* 12345678 * /Kで@KSDになる
KSDsym .dc.b 'AIG-KSD ' * KSD Symbol
*********************************************************************
* ワーク1
*********************************************************************
* 外部プログラム定義(この位置は変更しないこと;ksd.macでKSD_APIの算出に使っている)
* デフォルトのトップはSHIFT+登録でキーバッファー読みだし
.even
ExtFunc .dc.b .low.(SKtou>>8) * 起動キー(スキャンコード)
* $00なら起動しない(登録はされている)
* $1d=CRはSuperEDには使えない
.dc.b SKsft * シフト状態(B_SFTSNS、ただしbit0-3のみ有効)
* 0も一応可能(お勧めはしない)
.dc.l OnceActive * 起動アドレス
.dc.l 0 * ここに次のテーブルアドレスを書くとリンクする(V1.1)
*--------------------------------------------------------------------
* 固定値(この位置は変更しないこと;ksd.macで参照している)
API: .dc.l APImain * APIアドレス
Ver1: .dc.b 1 * バージョン番号整数桁
Ver2: .dc.b 7 * バージョン番号小数桁:01-09は表せない
.even
*--------------------------------------------------------------------
* 変化値
ProcAD .dc.l 0 * このプロセスの先頭アドレス(!=DevHead/常駐解除時に必要)
Dev_A5 .dc.l 0 * a5 save work
*
Kbuff .dc.l 0 * Key Buffer Address
KBsize .dc.l 0 * Key Buffer Size
rp .dc.l 0 * Key Buffer Read Pointer
wp .dc.l 0 * Key Buffer Write Pointer
Key1 .dc.l 0 * 起動キー保護のためなど
*
fdev .dc.b 0 * device driver flag : 0:常駐プログラム , <>0:デバイスドライバー
Kbmode .dc.b 0 * Kbuffの位置 : =0:プログラム後部 , <>0:高位メモリー
mode .dc.b 0 * 動作モード : =0:活動中 , 1:休止 , 2:完全停止
* =-1:外部プログラム起動無し活動 , =-2:一時活動
SnsSkip .dc.b 0 * B_KEYSNSをスキップする回数
Emode .dc.b 0 * 書込みFull時の処理 : 0:古いデータを消す , <>0:書き込めない部分は無視
JLock .dc.b 0 * 常駐解除ロックカウント : =0:解除可能 , >0:解除不可
.even
*********************************************************************
* APIルーチン
*********************************************************************
APImain:
* コマンドサーチ&実行
* d0.b=コマンド(未定義コマンドは:アルファベット->無視、数字->暴走)
* d0.l以外は保存
* あらかじめスーパーバイザーモードにしてから呼び出すこと
* B_系以外はユーザーモードでもよいが、device=で組み込まれている時は
* ユーザーモードではアクセス出来ないから。
* APImain内ではd0,d7,a0,a1以外破壊しないこと
* d1-d6,a2-a6は引数として予約
movem.l d1-d7/a0-a6,-(sp)
cmp.b #'A',d0 * アルファベットコマンド?
bcc AlphaCOM * Yes
* 数値コマンド
moveq.l #0,d7
move.b d0,d7 * .b -> .l
add.w d7,d7 * *2 (for word)
move.w CtableN(pc,d7.w),d7 * コマンドアドレス
bra 1f
*
AlphaCOM: * アルファベットコマンド
lea CtableC(pc),a0 * コマンド文字群
lea CtableA-2(pc),a1 * コマンドアドレス
@@: addq.w #2,a1
move.b (a0)+,d7
beq 2f * end of table
cmp.b d7,d0 * 一致?
bne @b * NO -> next command
* コマンド発見
move.w (a1),d7 * offset
1: *
moveq.l #0,d0 * for .b/.w -> .l
jsr DevHead(pc,d7.w) * 実行
*
2: movem.l (sp)+,d1-d7/a0-a6
rts
*
* コマンドジャンプアドレス
CtableN: * 数値コマンド(0~番号順)
.dc.w API_reserve-DevHead * 未定義
.dc.w API_CheckFull-DevHead * ->d0.l
.dc.w API_CheckEmpty-DevHead * ->d0.l
.dc.w API_Rcheck-DevHead * ->d0.b
.dc.w API_Read-DevHead * <-a2,d1.l ->d0.l
.dc.w API_Write-DevHead * <-a2,d1.l ->d0.l
.dc.w API_ReadMode-DevHead * ->d0.l
.dc.w API_ReadVer-DevHead * ->d0.w
.dc.w API_ReadSize-DevHead * ->d0.l
.dc.w API_ReadFree-DevHead * ->d0.l
.dc.w API_LinkEFunc-DevHead * <-a2 ->d0.l
.dc.w API_UnlinkEFunc-DevHead * <-a2 ->d0.l
.dc.w API_JLock-DevHead * ->d0.b
.dc.w API_JUnlock-DevHead * ->d0.b
.dc.w API_Read1-DevHead * ->d0.l
.dc.w API_Write1-DevHead * <-d1.b ->d0.l
.dc.w NonInp-DevHead * ->d0.l
.dc.w NonSns-DevHead * ->d0.l
.dc.w NonSft-DevHead * ->d0.l
.dc.w API_ExecEFunc-DevHead * <-a2 ->d0.l
.dc.w API_DevNameA-DevHead * <-a2 v1.7
CtableA: * アルファベットコマンド(下のアルファベットコマンド表と対)
.dc.w Clear-DevHead * なし
.dc.w Pause-DevHead * なし
.dc.w Active-DevHead * なし
.dc.w BuffActive-DevHead * なし
.dc.w OnceActive-DevHead * なし
.dc.w Stop-DevHead * なし
.dc.w WFMusi-DevHead * なし
.dc.w WFFull-DevHead * なし
CtableC: * アルファベットコマンド名(良く使う順にしておくのがよい)
.dc.b KSD_Clear
.dc.b KSD_Pause
.dc.b KSD_Active
.dc.b KSD_BuffActive
.dc.b KSD_OnceActive
.dc.b KSD_Stop
.dc.b KSD_WFMusi
.dc.b KSD_WFFull
.dc.b 0 * end of table
.even
*********************************************************************
* 基本内部ルーチン1:内部状態設定/参照
*********************************************************************
API_ReadVer: * バージョン読みだし
move.w Ver1(pc),d0 * d0.h.b=整数,d0.l.b=小数
API_reserve: * 未定義コマンド
rts
*--------------------------------------------------------------------
API_ReadMode: * 内部状態読みだし
* 'E/F','O/B/A/P/S'
* d0.l,d1.l,a0破壊
move.l #$2020_0000,d0 * ' ',' '
* 書き込みfull時
move.l #KSD_WFMusi.shl.16+KSD_WFFull,d1 * 無視/消す
tst.b Emode
beq @f * 消す
swap d1 * 消す/無視
@@: move.b d1,d0 * 2020_00FE
lsl.w #8,d0 * 2020_FE00
* 内部状態
moveq.l #0,d1 * for .b->.w
move.b mode(pc),d1 * -2,-1,0,1,2
addq.b #2,d1 * 0,1,2,3,4
lea ModeChar(pc),a0
move.b (a0,d1.w),d0 * 2020_FEAP
rts
* 動作状態キャラクター(mode+2=0~順)
ModeChar .dc.b KSD_OnceActive,KSD_BuffActive,KSD_Active,KSD_Pause,KSD_Stop
.even
*--------------------------------------------------------------------
API_ReadSize: * バッファーサイズ読みだし
move.l KBsize(pc),d0
rts
API_ReadFree: * バッファーフリーサイズ読みだし
* d0.l,d1.l,d2.l破壊
move.l KBsize(pc),d0 * KBsize
subq.l #1,d0 * -1
move.l rp(pc),d1
move.l wp(pc),d2
sub.l d2,d0 * -wp
cmp.l d1,d2 * wp>rp?
bcc @f
* wp<rp
sub.l d1,d0 * -rp
rts
@@: * wp>=rp
add.l d1,d0 * +rp
rts
*--------------------------------------------------------------------
WFFull: * 書き込みFull時:古いデータを消す
clr.b Emode
rts
*
WFMusi: * 書き込みFull時:無視
st.b Emode
rts
*--------------------------------------------------------------------
Stop: * KSDを停止させる
* 外部プログラム起動も不可能
move.b #MD_Stop,mode
rts
*
Pause: * 一時的に本来のキー入力へ戻す(休止)
* 外部プログラム起動は可能
move.b #MD_Pause,mode
rts
*
OnceActive: * KSDを一時的に有効にする(キーバッファー内容がある内だけ)
move.b #MD_OnceActive,mode
rts
*
BuffActive: * 外部プログラム起動は不可活動状態
st.b mode * mode=$ff=-1=MD_BuffActive
rts
*
Active: * KSDを有効にする(活動状態)
clr.b mode * mode=0=MD_Active
rts
*--------------------------------------------------------------------
Clear: * バッファークリア
clr.l wp
clr.l rp
*move.l wp(pc),rp * rp<-wp : 本当はこれでよい
rts
*--------------------------------------------------------------------
API_JLock: * 常駐ロック
* -> d0.b ロックカウント
* 特にチェックはしていないが、.bの+領域0~128段のみ可能
move.b JLock(pc),d0
addq.b #1,d0
move.b d0,JLock
rts
*
API_JUnlock: * 常駐アンロック
* -> d0.b ロックカウント
move.b JLock(pc),d0
subq.b #1,d0
bmi @f * マイナスにはしない
move.b d0,JLock
@@: rts
*********************************************************************
* 基本内部ルーチン2:バッファー状態読みだし
*********************************************************************
API_CheckFull: * バッファーフルチェック
* d0.l:1=full , 0=ok
bsr.s CheckFull * d0/d1破壊
seq d0
and.l #1,d0 * d0.l = 0(ok),1(full)
rts
*
CheckFull:
* eq=full , ne=ok
* d0.l,d1.l 破壊
move.l wp(pc),d0
move.l KBsize(pc),d1 * KBsize
subq.l #1,d1 * -1
cmp.l d0,d1 * wp==KBsize-1?
bne @f * no
* wp=KBsize-1のとき
tst.l rp * rp==0?
rts
*
@@: move.l rp(pc),d1
subq.l #1,d1
cmp.l d1,d0 * wp==rp-1
rts
*--------------------------------------------------------------------
API_CheckEmpty: * バッファー空チェック
* d0.l:1=empty , 0=ok
bsr.s CheckEmpty * d0破壊
seq d0
and.l #1,d0 * d0.l = 0(ok),1(empty)
rts
*
CheckEmpty:
* eq=empty , ne=ok
* d0.l 破壊
move.l wp(pc),d0
cmp.l rp(pc),d0 * rp==wp?
rts
*********************************************************************
* 基本内部ルーチン3:バッファー読み書き
*********************************************************************
API_Rcheck: * 先行入力
bsr CheckEmpty * 空?
bne Rcheck * -> d0.b(飛び先からrtsする),a0破壊
moveq.l #0,d0 * 空=$00を返す
rts
*
Rcheck: * rpを動かさないread
* 空の時は呼び出さないこと
* d0.b,a0 破壊
* d0.b <- Kbuff[rp]
move.l Kbuff(pc),a0 * Kbuff
add.l rp(pc),a0 * rp
move.b (a0),d0 * Kbuff[rp]->d0.b
rts
*--------------------------------------------------------------------
IncPt macro point
local L1
addq.l #1,d1 * p++
cmp.l KBsize(pc),d1 * p>=KBsize?
bcs L1 * no
moveq.l #0,d1 * Yes : p=0
L1: move.l d1,point
endm
*
*
API_Read1: * 1バイト読みだし
* d0.l -> データ($00~$ff)/エラー(-1)
bsr CheckEmpty * 空? d0破壊
beq ErrRW * Yes
moveq.l #0,d0 * for .b -> .l
bsr Read * d1,a0 破壊 -> d0.b(=.l)
rts
*
ErrRW: moveq.l #-1,d0 * バッファーが空
rts
*
*
API_Read: * バッファー内のみ読みだし
* a2 <- read buffer
* d1.l <- read要求 size
* d0.l -> 実read size
move.l d1,d3
beq 2f * size=0 -> 何もしない
moveq.l #0,d7 * size count=0
@@: bsr CheckEmpty * 空? d0破壊
beq 2f * Yes
bsr Read * d0,d1,a0 破壊
addq.l #1,d7 * read size
move.b d1,(a2)+
subq.l #1,d3
bne @b * dbraは.wループなので使えない
2: move.l d7,d0 * 実ReadSizeを返す
rts
*
Read:
* 空の時は呼び出さないこと
* d0.b,d1.l,a0 破壊
* d0.b <- Kbuff[rp++]
move.l Kbuff(pc),a0 * Kbuff
move.l rp(pc),d1 * rp
move.b (a0,d1.l),d0 * Kbuff[rp]->d0.b
RpINC: * d1=rpのこと
IncPt rp * rp++
rts
*--------------------------------------------------------------------
API_Write1: * 1バイト書き込み
* d1.b <- data
* d0.l -> 0=ok , -1=full
move.b d1,d2 * push data
bsr CheckFull * full? (d0,d1 破壊)
beq ErrRW * Yes
move.b d2,d0 * pop data
move.l Kbuff(pc),a0 * Kbuff
bsr Write
moveq.l #0,d0
rts
*
API_Write: * バッファー書き込み
* a2 <- write buffer
* d1.l <- write要求 size
* d0.l -> 実write size
move.l d1,d3
beq 5f * size=0 -> 何もしない
moveq.l #0,d7 * size count=0
move.l Kbuff(pc),a0 * Kbuff
@@: bsr CheckFull * d0,d1 破壊
bne 2f * fullでない
* Full:バッファーがいっぱい
tst.b Emode * 無視?
bne 5f * Yes : 書き込めただけのサイズを持って返る
1: * 古いデータを消して書き込む(実際にはrpを+1するだけ)
move.l rp(pc),d1 * rp
bsr RpINC * rp++
2: move.b (a2)+,d0 * 書き込むデータ
bsr Write
*
addq.l #1,d7 * write size
3: subq.l #1,d3
bne @b * dbraは.wループなので使えない
5: move.l d7,d0 * 実WriteSizeを返す
rts
*
Write:
* 空の時は呼び出さないこと
* d0.b <- data
* a0 <- Kbuff
* d1.l 破壊
move.l wp(pc),d1 * wp
move.b d0,(a0,d1.l) * d0.b->Kbuff[wp]
beq @f * $00の時はwpを動かさない=消す
IncPt wp * wp++
@@:
rts
*********************************************************************
* 基本内部ルーチン4:外部起動プログラム設定
*********************************************************************
API_LinkEFunc: * 外部起動プログラム追加(登録)
* a2 <- テーブルadrs
* -> d0.l : 0=出来た , 1=出来なかった
move.w (a2),d0 * 起動キーセット
lea ExtFunc(pc),a0 * リンクテーブル top
@@: cmp.w (a0),d0 * 同じキーセットがある?
beq 1f * Yes -> エラー
addq.w #KSD_EF_Next,a0
move.l (a0),d1 * next table adrs
beq @f * 最後->ここにつなぐ
* 最後ではない
move.l d1,a0 * to next table
bra.s @b
*
@@: * 最後を見つけた
move.l a2,(a0) * link
moveq.l #0,d0 * 正常登録の印
rts
1: * キーの重複があった
moveq.l #1,d0 * エラーの印
rts
*--------------------------------------------------------------------
API_UnlinkEFunc: * 外部起動プログラム解除
* a2 <- テーブルadrs
* -> d0.l : 0=出来た , 1=出来なかった
move.w (a2),d0 * w.hb <- 起動キーScanCode / w.lb <- 起動キーShift状態
bsr SearchEFKey * キーサーチ
beq @f * そのキーがあった
* そのキーはなかった
moveq.l #1,d0
rts
@@: * そのキーはあった
cmp.l a0,d1 * 一番最初?
beq @f * Yes : 一番最初のテーブルは消せないのでScanCode<-0だけする
* 一番最初以外のテーブル
* 解除するテーブルにつながっている次のテーブルを前のテーブルにつなぐ
move.l d1,a1
move.l KSD_EF_Next(a0),KSD_EF_Next(a1)
@@: clr.b (a0) * ScanCode<-0
moveq.l #0,d0 * そのキーはあった
rts
*--------------------------------------------------------------------
API_ExecEFunc: * 外部起動プログラム強制起動
* a2 <- テーブルadrs
move.w (a2),d0 * w.hb <- 起動キーScanCode / w.lb <- 起動キーShift状態
bsr SearchEFKey * 指定キーに相当する外部プログラム指定があるかを調べる
beq @f * そのキーがあった
* そのキーはなかった(起動できない)
moveq.l #1,d0
rts
*
@@: * 起動キーである
move.l KSD_EF_Exec(a0),a0
jsr (a0) * 外部ルーチン(d0-d2/a0-a2以外は破壊しないこと)
moveq.l #0,d0 * 起動出来た
rts
*--------------------------------------------------------------------
SearchEFKey: * 指定キーに相当する外部プログラム指定があるかを調べる
* d0.w.hb <- 起動キーScanCode(!=0)
* d0.w.lb <- 起動キーShift状態
* -> a0 : そのアドレス(a0=0:そのキーはなかった)
* -> d1 : 前のテーブルのアドレス
* eq=あった , ne=なかった
lea ExtFunc(pc),a0 * リンクテーブル top
move.l a0,d1 * 前のテーブル(先頭だけはそのテーブルそのもの)
@@: cmp.w (a0),d0 * キーが一致?
beq @f * Yes -> end(eq)
* キーは不一致 -> 次のテーブルへ
move.l a0,d1 * 前のテーブルアドレス保存
move.l KSD_EF_Next(a0),a0 * to next table
cmp.l #0,a0 * リンク最後?
bne @b * No
* リンクの最後まで行った
move.w d0,d0 * neにする
@@: rts
*********************************************************************
* 基本内部ルーチン5:デバイス名取得
*********************************************************************
API_DevNameA:
* a2 <- デバイス名格納エリア
lea DevName(pc),a0
moveq.l #8-1,d1 * -1 dbra
@@: move.b (a0)+,d0
cmp.b #' ',d0 * ' 'の直前まで
beq 2f
move.b d0,(a2)+
dbra d1,@b * または8バイトまで
2: clr.b (a2) * EOS
rts
*********************************************************************
* キー入力シュミレート
* レジスター破壊はIOCS/DOSと同じ(d0.lのみ)
* この部分は常にスーパーバイザーモードで走る
*********************************************************************
* KFLUSH
k_flush:
cmp.b #MD_Pause,mode
bge k_flush0 * >=1 : 休止/停止中 -> 通常
bsr CheckEmpty * 空?
beq k_flush0 * yes
* KSDキーバッファーあり
@@: * IOCSのキーバッファーのみクリア
bsr NonSns * B_KEYSNSの元のルーチン
tst.l d0 * キーが押されている?
beq @f * No
bsr NonInp * 元のB_KEYINP
bra.s @b * IOCSキーバッファーを消す
*
@@: move.b #1,SnsSkip * 次の1回のB_KEYSNSをスキップさせる
* キーバッファークリアを回避するため
k_flush0:
jmp 0.l * 元のKFLUSHが入る
* 飛び先でrtsする
KF_PATCH equ k_flush0+2
*--------------------------------------------------------------------
* B_SFTSNS
KeySft:
cmp.b #MD_Pause,mode
bge NonSft * >=1 : 休止/停止中 -> 通常
bsr CheckEmpty * 空?
beq NonSft * yes
* バッファー内容がある時
bsr NonSft * 元のB_SFTSNS
and.l #$fff0,d0 * "OPT2|OPT1|CTRL|SHIFTは押されていない"とする
*** moveq.l #0,d0 * "シフト系キーは押されていない"とする : これはASKで×
rts
*
NonSft: jmp 0.l * 元のB_SFTSNSが入る
* 飛び先でrtsする
SftPATCH equ NonSft+2
*--------------------------------------------------------------------
* B_KEYSNS
KeySns:
cmp.b #MD_Pause,mode
bge NonSns * >=1 : 休止/停止中 -> 通常
bsr CheckEmpty * 空?
beq NonSns * yes
* バッファーあり
tst.b SnsSkip * skip中?
beq @f * no
subq.b #1,SnsSkip
moveq.l #0,d0 * "キー入力はない"の印
rts
@@: *
move.l a0,-(sp)
move.l #$0001_0000|SKspc0,d0 * SPACE(scan code)
bsr Rcheck * -> d0.b : d0.l=$0001_35xx
move.l (sp)+,a0
rts
*
NonSns: jmp 0.l * 元のB_KEYSNSが入る
* 飛び先でrtsする
SnsPATCH equ NonSns+2
*--------------------------------------------------------------------
* B_KEYINP
KeyInp:
cmp.b #MD_Stop,mode
beq NonInp * 完全停止中 -> 通常
* mode=Active/BuffActive/OnceActive/Pause
movem.l d1/a0,-(sp)
cmp.b #MD_Pause,mode
beq I4 * 休止中 -> 通常キー入力
* mode=Active/BuffActive/OnceActive
* 活動中/一時活動中
bsr CheckEmpty * 空?
beq @f * Yes
* キーバッファー読みだし
* clr.w WK_B_KEYSNS * B_SFTSNSのワークをクリアする : これはASKで×
and.w #$fff0,WK_B_KEYSNS * "OPT2|OPT1|CTRL|SHIFTは押されていない"とする
* B_SFTSNSをワークから直接読み取っているソフトのため
move.l #SKspc0,d0 * SPACE(scan code)
bsr Read * -> d0.b : d0.l=$35xx
bra 2f
*
@@: * 活動中/一時活動中だがキーバッファーがない
* キーボード読みだし
* mode=Active/BuffActive/OnceActive
cmp.b #MD_OnceActive,mode * 一時動作?
bne I4 * No(動作中)
* mode=MD_OnceActive
bsr Pause * 休止状態に戻す
I4: * mode=Active/BuffActive/Pause
*
bsr NonInp * 元のB_KEYINP -> d0.w.hb:ScanCode , w.lb=ASC
*
cmp.b #MD_BuffActive,mode * 外部プログラム起動許可?
beq 2f * No
* mode=Active/Pause
* 外部プログラム起動
move.l d0,Key1 * 一旦保存
move.b WK_B_KEYSNS+1,d0
and.w #$ff0f,d0 * bit3-0のみ : d0.w.hb=Scan,lb=Shift
beq @f * $0000になるキーは外部起動として使えない(V1.61;Condrv対応)
bsr SearchEFKey * 指定キーに相当する外部プログラム指定があるかを調べる
bne @f * そのキーはない
* 起動キーである
movem.l d2/a1-a2,-(sp) * d0は保存の必要なし、d1/a0がすでに保存ずみ
move.l KSD_EF_Exec(a0),a0
jsr (a0) * 外部ルーチン(d0-d2/a0-a2以外は破壊しないこと)
movem.l (sp)+,d2/a1-a2
* V1.5でシフトキー離し待ちはやめた
* もともとはキー入力時にshift系キーが押されているとまずいことがあるからであるが、
* バッファーからの読みだし中はshift系=all offにするようにしたので不要になった
clr.l Key1 * キー入力は無しの印
@@: * 起動キーでない
move.l Key1,d0 * キーを戻す
2: movem.l (sp)+,d1/a0
rts
NonInp: jmp 0.l * 元のB_KEYINPが入る
* 飛び先でrtsする
InpPATCH equ NonInp+2
*********************************************************************
* デバイスドライバー:コマンド解析&初期処理
* デバイスドライバーは(たぶん)常にスーパーバイザーモードで走る。
*********************************************************************
Dev_start:
move.l a5,Dev_A5 * save リクエストヘッダーアドレス
rts
*********************************************************************
Dev_main:
movem.l d1-d7/a0-a6,-(sp) * push register
move.l Dev_A5(pc),a5 * a5 <- リクエストヘッダーアドレス
*
moveq.l #0,d0 * for .b -> .l
move.b 2(a5),d0 * d0.l <- コマンド番号
add.w d0,d0 * *2
lea comtable(pc),a1
move.w (a1,d0.w),d0 * read call offset address
jsr (a1,d0.w) * call subroutines
*
move.l d0,d1
move.b d1,3(a5) * set error code (low)
lsr.w #8,d1 * high -> low (8bit)
move.b d1,4(a5) * set error code (high)
movem.l (sp)+,d1-d7/a0-a6 * pop register
rts
*********************************************************************
.even
comtable: * コマンドアドレス(相対アドレス表)
.dc.w Dev_init-comtable * 初期化
.dc.w COM_ERR-comtable
.dc.w COM_ERR-comtable
.dc.w Dev_ioctrl_in-comtable * ioctrl in = 状態入力
.dc.w Dev_Read-comtable * 入力
.dc.w Dev_Rcheck-comtable * 先行入力
.dc.w API_CheckEmpty-comtable * 入力バッファーチェック
.dc.w Clear-comtable * バッファークリア
.dc.w Dev_Write-comtable * 出力(verify off)
.dc.w Dev_Write-comtable * 出力(verify on)
.dc.w API_CheckFull-comtable * 出力ステータスチェック
.dc.w COM_ERR-comtable
.dc.w Dev_ioctrl_out-comtable * ioctrl out = 制御コマンド
.even
*********************************************************************
* エラーコマンド
COM_ERR:
move.w #$5003,d0 * $50 = 中止&無視 , $03 = コマンドコードが不正
rts
*********************************************************************
Dev_Rcheck: * 先行入力
bsr API_Rcheck * -> d0.b
move.b d0,13(a5)
moveq.l #0,d0 * no error
rts
*--------------------------------------------------------------------
Dev_Read: * 入力
lea API_Read(pc),a0
bra @f
Dev_Write: * 出力(verify on/off)
lea API_Write(pc),a0
@@:
move.l 14(a5),a2 * buffer
move.l 18(a5),d1 * size : COOKED modeでは常に1(RAW modeでは>=1)
jsr (a0) * Read/Write
move.l d0,18(a5) * 実Read/WriteSizeを返す
moveq.l #0,d0 * no error
rts
*--------------------------------------------------------------------
Dev_ioctrl_out: * ioctrl out = 制御コマンド
move.l 14(a5),a2 * buffer
@@: move.b (a2)+,d0 * 1文字コマンド(大文字のみ)
beq NonErr * $00まで
cmp.b #'A',d0
bcs @b * APIコマンドは使えなくしておく
bsr APImain * コマンドサーチ
bra @b
Dev_ioctrl_in: * ioctrl in = 状態入力
* mode/ver/size/free
move.l 18(a5),d0 * size
cmp.l #KSD_ST_SIZE,d0 * size>=KSD_ST_SIZE?
bcs NonErr * No : sizeが足りない->何も返さない
move.l 14(a5),a2 * buffer
* mode
bsr API_ReadMode * d0.l,d1.l,a0破壊
rol.w #8,d0 * APIとは順が違うので変換
move.w d0,(a2)+
move.b #KSD_SEP,(a2)+ * セパレーター
* version
move.l a2,a0 * ここから先はa0に書き込む
bsr MakeVerStr * バージョン番号文字列化
* buffer size
move.l KBsize(pc),d0 * KBsize
bsr Store10
* free
bsr API_ReadFree * d0.l=Free,d1.l,d2.l破壊
bsr Store10
NonErr: * IOCTRL IN/OUTはエラーを返さない
* サイズを書き込んでも無効(常に0)
moveq.l #0,d0 * non error
rts
Store10:
move.b #KSD_SEP,(a0)+ * セパレーター
FPACK __LTOS * d0.l(符号つき) -> 10進文字列化
rts
*
MakeVerStr:
* バージョン番号文字列作成
* a0.l = バッファー
moveq.l #0,d0
move.b Ver1(pc),d0 * 整数桁
FPACK __LTOS * d0.l(符号つき) -> 10進文字列化
move.b #'.',(a0)+ * 小数点
moveq.l #0,d0
move.b Ver2(pc),d0 * 小数桁
FPACK __LTOS * d0.l(符号つき) -> 10進文字列化
rts
*********************************************************************
KEEP_END: * 常駐:固定部分最後+1
* これ以降はキーバッファーになる
*********************************************************************
* 非常駐ルーチン
*********************************************************************
* 外部参照
* 外部参照するルーチンはプログラムの後部にリンクされる。
* 従って、常駐後には初期化ルーチンとともに消されるので使えない。
.xref _DevCheck
.xref _DevCheck2
.xref SetDevLink
.xref ResetDevLink
.xref Atoi
.xref Print10
*--------------------------------------------------------------------
* 初期化ルーチンは、コマンドラインから起動の時はユーザーモードで、
* デバイスドライバーの時はスーパーバイザーモードで走る(はず)。
* 本当は、デバイスドライバー常駐のものを操作する時のため、
* ここでスーパーバイザーモードにしてからInitSubを呼び出したい。
* しかしそうすると、setblockがエラーを出してしまう。
* したがって、複雑になるが、InitSub中で必要時のみスーパーバイザーにする。
*--------------------------------------------------------------------
main: * 常駐
lea.l initsp(pc),sp * PROGRAM=の時スタックオーバーを起こすので
* スタックを変更しておく
* clr.b fdev * コマンドライン組み込み
bsr InitSub * 初期化
move.w d0,-(sp) * exit(?)
tst.l d1
bne @f
* 常駐関係以外終了
DOS _EXIT2
*
@@: * デバイスリンクに入り込む
lea DevHead(pc),a0
bsr SetDevLink
*
* 常駐終了
move.l d1,-(sp) * 常駐サイズ
DOS _KEEPPR
*--------------------------------------------------------------------
Dev_init: * 初期化
st.b fdev * DEVICE=組み込み
bsr ChangeLine * コマンドライン変換
bsr PrCRLF * 1行改行してからメッセージを出す
*
lea cline0(pc),a2
bsr InitSub * 初期化
tst.l d1
beq @f * 常駐以外終了
* 常駐終了
add.l #DevHead,d1 * 常駐部最終アドレス
move.l d1,14(a5)
@@:
rts
* init時のd0.l<>0は白帯にならずに組み込めないメッセージとなる
*--------------------------------------------------------------------
ChangeLine:
* DEVICE=形式のパラメーターをコマンドライン型に変換する
* 読み取りルーチン共用化のため
move.l 18(a5),a0 * 元のコマンドライン
* 最初の00まではプログラム名なので飛ばす
@@: tst.b (a0)+
bne @b
*
lea cline(pc),a2 * 変換後ライン
moveq.l #0,d1 * length
CL1: tst.b (a0)
beq CLend * 0,0で終了
@@: addq.l #1,d1 * len++
move.b (a0)+,(a2)+
bne @b
* 0をスペースに直す
move.b #' ',-1(a2)
bra.s CL1
*
CLend: clr.b (a2) * EOS
move.b d1,cline0
rts
*--------------------------------------------------------------------
PrintDevName:
* デバイス名表示
* 改行付き
bsr PrintDevName0
bsr PrCRLF * 改行
rts
PrintDevName0:
* デバイス名表示
* エラー表示のため改行しない
* (a0.l/d1.lは壊さないように)
movem.l a0/d1,-(sp)
*
pea DeviceMes(pc)
DOS _PRINT
addq.w #4,sp
*
lea.l DevName-DevHead(a0),a0
moveq.l #0,d0 * for .b = .w
moveq.l #8-1,d1 * デバイス名は8文字まで
@@: move.b (a0)+,d0
move.w d0,-(sp)
DOS _PUTCHAR
cmp.w #' ',(sp)+ * スペースを1つ表示したら終了
dbeq d1,@b
*
movem.l (sp)+,d1/a0
rts
*--------------------------------------------------------------------
PrintBuff:
* バッファー状態表示
* 常駐している時にその常駐しているルーチンのバッファー状態を表示する
* a0=DevHeadアドレス
* バッファーアドレス
pea BuffAdMes(pc)
DOS _PRINT
addq.w #4,sp
move.l Kbuff-DevHead(a0),d0
move.l a0,-(sp)
lea SizeAsc(pc),a0
FPACK __HTOS
move.l (sp)+,a0
pea SizeAsc(pc)
DOS _PRINT
addq.w #4,sp
* 高位メモリー?
tst.b Kbmode-DevHead(a0)
beq @f
pea MemHigh(pc) * Yes
DOS _PRINT
addq.w #4,sp
@@: bsr PrCRLF
*
* バッファーサイズ
pea BuffSzMes(pc)
move.l KBsize-DevHead(a0),-(sp)
bsr PrMesDec
* rp
pea RpMes(pc)
move.l rp-DevHead(a0),-(sp)
bsr PrMesDec
* wp
pea WpMes(pc)
move.l wp-DevHead(a0),-(sp)
bsr PrMesDec
*
lea 8*3(sp),sp
*
rts
PrMesDec:
* メッセージ+10進数表示+改行
* PrMesDec(mes,dec)
move.l 8(sp),-(sp)
DOS _PRINT
addq.w #4,sp
move.l 4(sp),d0
bsr Print10
PrCRLF: * 改行
pea CrLf(pc)
DOS _PRINT
addq.w #4,sp
rts
MemHigh:
.dc.b '(高位)',0
.even
*--------------------------------------------------------------------
PrintMode:
* 状態表示
* a0=DevHeadアドレス
moveq.l #KSD_ReadMode,d0
move.l KSD_API(a0),a0 * APIアドレス
jsr (a0) * d0.l = 状態 : ' '=無視,'E/F','O/B/A/P/S'
moveq.l #4-1,d6 * 4 <- .l = 4*.b
@@: bsr PrStatus * 再起呼び出しだ!
lsr.l #8,d0 * ' 'は無視される
dbra d6,@b
PrStatus:
move.l d0,-(sp)
lea ExgFlags-6(pc),a0 * 後で+6するため-6しておく
@@: addq.w #6,a0
tst.b 1(a0) * Option名
beq @f * 全終了
cmp.b 1(a0),d0 * =Option?
bne @b * No -> check next option
move.w 4(a0),a0
add.l #DevHead,a0 * Message(起動プログラム内)
pea (a0)
DOS _PRINT
addq.w #4,sp
@@: move.l (sp)+,d0
rts
*--------------------------------------------------------------------
* コマンドライン解析(a2=コマンドライン)
* この中ではa0は壊さないこと(プロセス管理ポインタを参照するため)
ChkARG:
tst.b (a2)+ * コマンドラインサイズ = 0?
bne arglp * No
* コマンドラインがない(プログラム名のみ)
move.w #$ff00,d0 * 注意(.b=0,.w!=0)
rts
*
arglp:
@@: * 空白飛ばし
move.b (a2)+,d0
cmp.b #' ',d0
beq @b
cmp.b #$09,d0 * TAB
beq @b
subq.w #1,a2 * a2が1つ進んでいるので戻す
*
tst.b d0 * end?
beq eos * Yes
* オプションは -? or /?
cmp.b #'-',d0
beq chkopt
cmp.b #'/',d0
beq chkopt
getarg: * オプション以外の引数はキーバッファーサイズ指定とみなす
* SizeAscにそれを転送
lea.l SizeAsc(opc),a3
@@: move.b (a2)+,d0
cmp.b #' ',d0 * SPCがあったら終わり
beq @f
cmp.b #$09,d0 * TABがあったら終わり
beq @f
move.b d0,(a3)+
bne @b
eos: * EOSを入れたら終了(この後にオプションはない)
moveq.l #0,d0 * ok(.b=0,.w=0)
rts
*
@@: clr.b (a3) * EOS
bra arglp * オプションチェックに戻る
chkopt: * オプションチェック
addq.w #1,a2 * skip '-' or '/'
move.b (a2)+,d0
beq argerr * -/のみでオプションがない
and.b #%11011111,d0 * 大文字化
*
lea ComFlags-6(pc),a6 * 後で+6するため-6しておく
tst.b fdev * DEVICE=?
beq @f * no
* DEVICE=時
lea DevFlags-6(pc),a6 * 後で+6するため-6しておく
@@: addq.w #6,a6
tst.b 1(a6) * Option名
beq argerr * 全てのオプションと比較終了 -> 規定外オプション
cmp.b 1(a6),d0 * オプションチェック
bne @b * 不一致
tst.b (a6) * すでにフラグがセットされている?
bne arglp * Yes : 飛ばす(2重指定なのでargerrにしてもよい)
st.b (a6) * セット
bra arglp * コマンドライン処理へ戻る
argerr:
moveq.l #-1,d0 * エラー(.b<>0)
rts
*--------------------------------------------------------------------
ChkVct macro vcno,adrs
* KSDで使っているベクターの書き替えチェック
move.w #vcno,-(sp)
DOS _INTVCG
addq.w #2,sp
lea.l adrs-DevHead(a0),a6 * 飛び先アドレス
cmp.l d0,a6
bne Err_Vect * ベクターが書き替えられているので常駐解除不可
endm
*--------------------------------------
InitSub: * 初期化 -> d0.l:status , d1.l=常駐サイズ
* a5は壊さないこと
move.l a0,d7 * a0保存
lea SizeAsc(pc),a0
bsr MakeVerStr * バージョン番号文字列化
pea title1(pc) * タイトル前半表示
DOS _PRINT
pea SizeAsc(pc) * バージョン番号
DOS _PRINT
pea title2(pc) * タイトル後半表示
DOS _PRINT
lea 4*3(sp),sp
move.l d7,a0 * a0復帰
*
bsr ChkARG * コマンドライン引数チェック
tst.b d0 * (.wではない)
bne usage * 引数がおかしい
*
* このあたりではd0/a2は破壊しないこと
*
movem.l d0/a2,-(sp) * 重要
clr.l -(sp) * デバイス名格納せず
pea KSDsym(pc) * 隠しデバイス名
bsr _DevCheck2 * デバイスチェック
addq.l #8,sp
move.b d0,d7 * d7.b : 0=常駐してない(a0=不変=自己メモリーブロック)
* $ff=常駐している(a0=デバイスヘッダーアドレス=DevHead)
movem.l (sp)+,d0/a2 * 重要
*
tst.b rflag * -r : 常駐解除?
beq keep * no
*
* 常駐解除(device=では絶対に来ない)
*
tst.b d7 * 常駐している?
beq Err_NoKp * No -> error
*
* すでに常駐しているものを解除
*
* DEVICE=で常駐している時は解除不可
lea.l fdev-DevHead(a0),a1
IOCS _B_BPEEK * スーパーバイザーの中を覗くことがあるため
tst.b d0
bne Err_Dev * DEVICE=で組み込まれている
*
* ここに来るのはコマンドライン常駐の時のみ=ksdは必ずユーザーモード領域にいる
* 常駐ロックチェック
tst.b JLock-DevHead(a0) * =0?
bne Err_Lock * No:常駐ロック中
*
* キーベクターが変更されていないか調べる
ChkVct _KFLUSH,k_flush
ChkVct _B_SFTSNS+$100,KeySft
ChkVct _B_KEYSNS+$100,KeySns
ChkVct _B_KEYINP+$100,KeyInp
*
move.l ProcAD-DevHead(a0),-(sp) * このプロセスの先頭アドレス
DOS _MFREE * 自己プロセスメモリー解放
addq.w #4,sp
tst.l d0
bmi Err_Kai * なぜかメモリー解放出来ない時
*
* 以下の処理は、解放したメモリー内にあるプロセスを参照しているので
* 非常に危険な処理である。マルチタスク環境下では致命的な問題を起こすかもしれない。
tst.b Kbmode
beq @f
* 高位メモリーにあるバッファーを解放
move Kbuff-DevHead(a0),-(sp) * Kbuffのアドレス=*Kbuff
DOS _MFREE * メモリー解放
addq.w #4,sp
tst.l d0
bmi Err_WkNk * なぜかメモリー解放出来ない時
* エラーが出た場合、メインプロセスがなくワークのみが残ることになる。
* 非常によろしくない。一言で言えば手抜きである。
@@: * デバイスリンク解除
bsr ResetDevLink * a0=DevHead
*
* キーベクター戻し
*(これ以降のルーチンでエラーが出ないところで戻しを行う)
move.l KF_PATCH-DevHead(a0),-(sp)
move.w #_KFLUSH,-(sp)
DOS _INTVCS
move.l SftPATCH-DevHead(a0),-(sp)
move.w #_B_SFTSNS+$100,-(sp)
DOS _INTVCS
move.l SnsPATCH-DevHead(a0),-(sp)
move.w #_B_KEYSNS+$100,-(sp)
DOS _INTVCS
move.l InpPATCH-DevHead(a0),-(sp)
move.w #_B_KEYINP+$100,-(sp)
DOS _INTVCS
lea 6*4(sp),sp
*
* 常駐解除正常終了
pea.l MesRelease(pc) * 解除メッセージ
DOS _PRINT
addq.w #4,sp
moveq.l #0,d1 * 常駐しない
moveq.l #0,d0 * 正常終了:exit(0)
rts
************************************
SetVect macro adrs,no,patch
* キーベクター保存&書き替え
pea adrs(pc) * これは次のINTVCSのため
move.w #no,-(sp)
DOS _INTVCG
move.l d0,patch
DOS _INTVCS
addq.w #6,sp
endm
SetFlags2Mode:
* オプションテーブルを見ながらモードを設定する
* a3,a6破壊 (d1.lは壊さないように)
* a0=プログラムベースアドレス
lea ExgFlags-6(pc),a6 * 後で+6するため-6しておく
@@: addq.w #6,a6
tst.b 1(a6) * Option名
beq @f * 全終了
tst.b (a6) * Optionがセットされている?
beq @b * No -> check next option
* オプションはセットされている
* そのオプションをセットするルーチンを呼び出す
* 呼び出すのは常駐プログラム内のもの
move.w 2(a6),a3 * 起動プログラム内でのアドレスoffset
jsr (a0,a3.w) * a0+a3.w ; 常駐プログラム内/起動プログラム内
move.w 4(a6),a3
add.l #DevHead,a3 * Message(起動プログラム内)
pea (a3)
DOS _PRINT
addq.w #4,sp
addq.l #1,d6 * セットした回数
bra @b
@@:
rts
************************************
AlreadyKeep:
* すでに常駐している
tst.b hflag
bne Err_2Kp * /Hがある -> 2重常駐エラー
tst.b fdev * 今DEVICE=内で2重常駐しようとしている?
bne Err_2Kp * Yes -> error(DEVICE=組み込みでは2重常駐エラーにする)
*
* 常駐時に、コマンドラインからもう一回起動するとモード変更か状態表示になる
* a0=常駐しているルーチンのメモリ管理ポインタ
clr.l a1
IOCS _B_SUPER * super visor mode
move.l d0,-(sp) * DEVICEの中を覗くため
* 状態変更
moveq.l #0,d6
bsr SetFlags2Mode * Flag -> モード設定
tst.l d6 * モード変更された?
bne StatusOk
*
* モード変更はしていないので状態表示を行う
bsr PrintDevName * デバイス名
bsr PrintBuff * バッファー状態
bsr PrintMode * 内部状態
StatusOk:
move.l (sp)+,d0
bmi @f * 元からsuper visorであった
move.l d0,a1
IOCS _B_SUPER * user mode
@@: *
moveq.l #0,d1 * 常駐しない
moveq.l #0,d0 * 正常終了:exit(0)
rts
*
* 常駐
*
keep: tst.b d7 * すでに常駐している?
bne AlreadyKeep * Yes
* KSDは常駐していない
tst.w d0 *(ここまでd0を破壊してはいけない)
bne usage * バッファー指定がない
*
* デバイス名を変更する時はここで行う
tst.b kflag * デバイス名を@KSDにする?
beq @f * No
* @KEY -> @KSD ; 後ろ2文字のみ違う
move.w #('S'<<8)|'D',DevName+2 * ここはワードで書き込める
@@: * 同名デバイスもない?
movem.l a0-a2,-(sp) * 重要
pea DevName(pc)
bsr _DevCheck
addq.l #4,sp
movem.l (sp)+,a0-a2 * 重要
tst.b d0
bne Err_DevUse * 同名デバイスがある
* 同名デバイスもない
*
* 常駐処理
* キーバッファーサイズ取得
lea SizeAsc(pc),a6
bsr Atoi
move.l d0,KBsize
move.l d0,d1 * キーバッファーサイズ保存
ble Err_KbSz * サイズ指定がおかしい(<=0)
*
tst.b fdev
bne @f * -> DEVICE=常駐
* コマンドライン常駐時のみ
* プログラム起動時にはフリーエリアの全てが起動プログラムに割り当てられているため、
* これを必要部分以外解放する。そうしないとMALLOCが効かない。
* DEVICE=のときは不要(MALLOC出来る)。
* a0=プログラムメモリ管理ポインタ
* a1=プログラム終了アドレス+1(.data,.bssを含む)
lea MPSIZ(a0),a0 * メモリー管理ポインタ分を飛ばす
move.l a0,ProcAD * このプロセスの先頭アドレス(!=DevHead)保存
sub.l a0,a1 * 当プログラムサイズ
tst.b hflag * 高位メモリー確保?
bne 1f * Yes
* 低位メモリー確保の時はそのメモリー分も入れておく必要がある
add.l d1,a1 * d1=キーバッファーサイズ
1: move.l a1,-(sp) * 確保する領域サイズ
move.l a0,-(sp) * 確保する領域の先頭アドレス
DOS _SETBLOCK * 領域変更
addq.w #4*2,sp
tst.l d0
bmi Err_StBk * 領域が変更できない時=エラー
*
@@: move.l #KEEP_END,Kbuff * キーバッファーアドレス記憶
*
tst.b hflag * 高位メモリー確保?
beq @f * No
* 高位メモリー確保
move.l d1,-(sp) * キーバッファーサイズ
move.w #2,-(sp) * 高位メモリー
DOS _MALLOC2
addq.w #6,sp
tst.l d0
beq Err_Mem * ワークが確保できない
move.l d0,Kbuff * アドレス記憶
st.b Kbmode * 高位メモリーの印
moveq.l #0,d1 * 高位にワークをとったので追加常駐サイズは最小でいい
@@: add.l #KEEP_END-DevHead,d1 * 本体常駐サイズ
*
* キーベクター保存&書き替え
*(これ以降のルーチンでエラーが出ないところで書き替えを行う)
SetVect k_flush,_KFLUSH,KF_PATCH
SetVect KeySft,_B_SFTSNS+$100,SftPATCH
SetVect KeySns,_B_KEYSNS+$100,SnsPATCH
SetVect KeyInp,_B_KEYINP+$100,InpPATCH
*
pea MesKeep(OPC) * 常駐メッセージ
DOS _PRINT
addq.w #4,sp
*
* フラグによるモードセット(すべてのフラグが有効ではない)
* d1.lを壊さないように
lea DevHead(pc),a0 * このプログラム内を参照
bsr PrintDevName * デバイス名表示
bsr SetFlags2Mode * Flag -> モード設定
moveq.l #0,d0 * exit(0)
rts
*--------------------------------------
* エラー処理
*--------------------------------------
Err_DevUse: * デバイス名がすでに使われている
lea DevHead(pc),a0 * このプログラム内を参照
bsr PrintDevName0
lea.l ErrDevUse(pc),a0
bra.s error
Err_KbSz: * キーバッファーサイズ指定がおかしい
lea.l ErrIllSize(pc),a0
bra.s error
Err_StBk: * SetBlock出来ない
* lea.l ErrCantKpBuff2(pc),a0
* bra.s error
Err_Mem: * メモリーが不足している
lea.l ErrCantKpBuff(pc),a0
bra.s error
Err_NoKp: * 常駐していないのに解除しようとした
lea.l ErrNoKukikomi(pc),a0
bra.s error
Err_2Kp: * 2重常駐
lea.l ErrAlreadySet(pc),a0
bra.s error
*
Err_Vect: * ベクターが書き替えられている
lea.l ErrCantKey(pc),a0
bra.s error
Err_Dev: * DEVICE=で組み込まれている
lea.l ErrCantDevice(pc),a0
bra.s @f
Err_WkNk: * ワークエリアが解放できない
lea.l ErrCantResBuff(pc),a0
bra.s @f
Err_Lock: * 常駐ロックされている
lea.l ErrCantJLock(pc),a0
@@: bsr PrintErr
Err_Kai: * 常駐解除不可
lea.l ErrCantRelease(pc),a0
bra.s error
*
usage: * 使用法
lea.l MesUsage(pc),a0
error: bsr PrintErr
lea CrLf(pc),a0
bsr PrintErr
moveq.l #0,d1 * 常駐しない
moveq.l #2,d0 * exit(2)
rts
*
PrintErr
* (a0)エラー出力へメッセージ表示
move.w #2,-(sp) * STDERR
pea.l (a0)
DOS _FPUTS
addq.w #2+4,sp
rts
*********************************************************************
* メッセージなど
*********************************************************************
.even
title1 .dc.b 'KeySimulateDriver V',0
title2 .dc.b ' Copyright 1997,98 by AIG-Soft',$0d,$0a
* .dc.b ' Debug中 v015',$0d,$0a
.dc.b 0
MesKeep .dc.b '組み込みました',$0d,$0a,0
MesRelease .dc.b '解除しました',$0d,$0a,0
ErrNoKukikomi .dc.b '組み込まれていません',$0d,$0a,0
*
*ErrCantKpBuff2 .dc.b 'SetBlock不可で'
ErrCantKpBuff .dc.b 'キーバッファーが確保できません',0
ErrAlreadySet .dc.b 'すでに組み込まれています',0
ErrIllSize .dc.b 'キーバッファーサイズが異常です',0
ErrDevUse .dc.b 'はすでに使用されています',0
*
ErrCantDevice .dc.b 'DEVICE=で組み込まれています.',0
ErrCantResBuff .dc.b 'キーバッファーが解放できません.',0
ErrCantJLock .dc.b '常駐ロックされています.',0
ErrCantKey .dc.b 'ベクターが書き替えられています.' * 次につながる
ErrCantRelease .dc.b 'KSDは解除できません',0
*
MesUsage .dc.b 'KSD [/h /r /e /f /p /a /b /c /o /s /k] バッファーサイズ[K]',0
BuffAdMes .dc.b 'バッファーアドレス:',0
BuffSzMes .dc.b 'バッファーサイズ :',0
RpMes .dc.b 'Rp:',0
WpMes .dc.b 'Wp:',0
StopMes .dc.b '完全停止状態',$0d,$0a,0
PauseMes .dc.b '休止状態',$0d,$0a,0
OnceActiveMes .dc.b '一時' * 次につながる
ActiveMes .dc.b '活動状態',$0d,$0a,0
BuffActiveMes .dc.b '外部プログラム起動なし活動状態',$0d,$0a,0
WFFullMes .dc.b '書込Full:古いデータ消去',$0d,$0a,0
WFMusiMes .dc.b '書込Full:無視',$0d,$0a,0
DeviceMes .dc.b 'デバイス名:',0
ClearMes .dc.b 'キーバッファーをクリアしました' * 次へつながる
CrLf .dc.b $0d,$0a,0
*********************************************************************
* オプション
*********************************************************************
* オプション名はコマンド名と同じにする
* PrintModeでも参照する
.even
* .dc.b work,フラグキャラクター
* .dc.w 処理ルーチンoffset,メッセージoffset(無い時は0,0)
* 1オプション分 1+1+2+2=6バイト
ComFlags: * コマンドライン時有効フラグ
rflag .dc.b 0,'R' * 常駐解除フラグ
.dc.w 0,0
DevFlags: * デバイスドライバ時にも有効フラグ
hflag .dc.b 0,'H' * 高位メモリー確保フラグ
.dc.w 0,0
kflag .dc.b 0,'K' * デバイス名を@KSDにする
.dc.w 0,0
* 常駐後にも変更可能なオプション
ExgFlags: * 同一系オプションは下の方が優先順位が高い
cflag .dc.b 0,'C' * clear
.dc.w Clear-DevHead,ClearMes-DevHead
oflag .dc.b 0,'O' * Once Active
.dc.w OnceActive-DevHead,OnceActiveMes-DevHead
aflag .dc.b 0,'A' * active
.dc.w Active-DevHead,ActiveMes-DevHead
bflag .dc.b 0,'B' * buff active
.dc.w BuffActive-DevHead,BuffActiveMes-DevHead
pflag .dc.b 0,'P' * pause
.dc.w Pause-DevHead,PauseMes-DevHead
sflag .dc.b 0,'S' * Stop
.dc.w Stop-DevHead,StopMes-DevHead
eflag .dc.b 0,'E' * WriteFull時 無視
.dc.w WFMusi-DevHead,WFMusiMes-DevHead
fflag .dc.b 0,'F' * WriteFull時 古いデータを消す
.dc.w WFFull-DevHead,WFFullMes-DevHead
.dc.b 0,0 * end of table
*********************************************************************
* 非常駐ルーチンが使うワーク
*********************************************************************
.bss
.even
cline0 .dc.b 0 * 変換後コマンドラインサイズ
cline .ds.b 256 * コマンドライン変換
SizeAsc .ds.b 96 * キーバッファーサイズを示す文字列
.stack
.even
.ds.l 512 * スタック(コマンドライン起動時のみ使用)
initsp:
*********************************************************************
.end main